package com.timguan.render.dataprocessor.processor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.timguan.render.api.entity.cms.CMSDataProcessorParamInfo;
import com.timguan.render.api.entity.dataprocessor.CMSItemInfo;
import com.timguan.render.dataapi.domain.CmsDataDO;
import com.timguan.render.dataprocessor.filter.DataFilterChain;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by guankaiqiang on 2015/3/21.
 */
public abstract class DataProcessor implements Serializable, InitializingBean {
    private static final Logger logger = LoggerFactory.getLogger(DataProcessor.class);
    /**
     * 处理器参数名称
     */
    //数据处理器入参数据列表Id参数名listId
    public static final String PROCESSOR_PARAM_DATALISTID = "listId";
    //分类Id
    public static final String CATEGORY_ID_PARAM = "categoryId";
    //秒杀提前focus
    public static final String ADVANCE = "advance";
    //数量控制
    public static final String MAX_COUNT_PARAM = "count"; //数量控制
    //开始展示时间
    public static final String START_DISPLAY_TIME = "startDisplayTime";
    //结束展示时间
    public static final String END_DISPLAY_TIME = "endDisplayTime";
    //获取当前的页码
    public static final String PAGE_NUMBER_PARAM = "pageNumber";
    //分页处理器 todo 分页优化
    public static final String PAGINATION_PROCESSOR = "paginationDataListProcessor";

    //间隔时间
    public static final String PRODUCT_TIME_INTERVAL = "timeInterval";

    /**
     * 系统属性名称
     */
    //聚类标签
    public static final String TAG = "tag";
    //商品ID
    public static final String ITEM_ID = "itemId";
    //imgURL
    public static final String IMG_URL = "imgUrl";
    //HTML
    public static final String HTML = "html";
    //需要添加SPM前缀的字段名称
    public static final String LINK = "link";
    public static final String H5LINK = "h5link";
    public static final String VID="_vid";
    //type
    public static final String DATA_TYPE = "_type";
    public static final String ACTION_TYPE = "_action";
    //价格
    public static final String PRICE = "_price";
    //售罄状态
    public static final String SOLDOUT_STATUS = "_status";
    //库存
    public static final String STOCK = "_stock";
    public static final String CARD_ID = "cardId";
    public static final String BAG_ID = "bagId";
    public static final String BRAND_ID="brandId";
    public static final String ACTIVITYINFO="promotionInfo";
    public static final String ID_MARK = "idMark";
    protected String description;
    protected CMSDataProcessorParamInfo[] paramInfos;
    //被添加的时候是否需要创建数据列表
    protected boolean needCreateDatalistWhenUsed = false;

    public boolean isNeedCreateDatalistWhenUsed() {
        return needCreateDatalistWhenUsed;
    }

    public String getDescription() {
        return description;
    }

    public CMSDataProcessorParamInfo[] getParamInfos() {
        return paramInfos;
    }

    protected DataFilterChain dataFilterChain = new DataFilterChain();

    public List<Object> getResult(CommonParametersWrapper commonParametersWrapper, String params) {
        List<Object> result = null;
        try {
            result = execute(commonParametersWrapper, JSON.parseObject(params, new TypeReference<Map<String, String>>() {
            }));
        } catch (Exception e) {
            logger.error("processor处理失败,commonParameters:{},params:{}", commonParametersWrapper, JSON.toJSONString(params), e);
        }
        if (result == null) {
            result = new ArrayList<Object>();
        }
        return result;
    }

    /**
     * processor处理数据的核心逻辑
     *
     * @param commonParametersWrapper
     * @param params
     * @return
     */
    protected abstract List<Object> execute(CommonParametersWrapper commonParametersWrapper, Map<String, String> params);

    /**
     * 设置spm值
     *
     * @param wrapper
     * @param dataEntry
     * @param id
     * @return
     */
    protected Map<String, String> setSpm(CommonParametersWrapper wrapper, Map<String, String> dataEntry, int id) {
        if (dataEntry != null) {
            //添加SPM值
            String link = dataEntry.get(LINK);
            String h5link = dataEntry.get(H5LINK);
            if (StringUtils.isNotBlank(link) || StringUtils.isNotBlank(h5link)) {
                if (StringUtils.isNotBlank(link)) {
                    dataEntry.put(LINK, wrapper.appendSpmPrefix(link, id));
                }
                if (StringUtils.isNotBlank(h5link)) {
                    dataEntry.put(H5LINK, wrapper.appendSpmPrefix(h5link, id));
                }
            }
            String vid = wrapper.getVid(link, id);
            dataEntry.put(VID, vid);
        }
        return dataEntry;
    }

    //接口数据增加spm和_vid
    protected CMSItemInfo setSpm(CommonParametersWrapper wrapper, CMSItemInfo cmsItemInfo, int id) {
        if (cmsItemInfo != null) {
            //添加SPM值
            String link = cmsItemInfo.getLink();
            String h5link = cmsItemInfo.getH5link();
            if (StringUtils.isNotBlank(link) || StringUtils.isNotBlank(h5link)) {
                if (StringUtils.isNotBlank(link)) {
                    cmsItemInfo.setLink(wrapper.appendSpmPrefix(link, id));
                }
                if (StringUtils.isNotBlank(h5link)) {
                    cmsItemInfo.setH5link(wrapper.appendSpmPrefix(h5link, id));
                }
            }
            //
            cmsItemInfo.set_vid(wrapper.getVid(link, id));
        }
        return cmsItemInfo;
    }

    /**
     * 数据类型
     *
     * @param dataEntry
     * @return
     */
    private CMSItemInfo.DataType parseDataType(Map<String, String> dataEntry) {
        if (dataEntry != null) {
            if (StringUtils.isNotBlank(dataEntry.get(ITEM_ID)) && !"0".equalsIgnoreCase(dataEntry.get(ITEM_ID))) {
                return CMSItemInfo.DataType.ITEM;
            } else if (StringUtils.isNotBlank(dataEntry.get(IMG_URL))) {
                return CMSItemInfo.DataType.IMG;
            } else if (StringUtils.isNotBlank(dataEntry.get(HTML))) {
                return CMSItemInfo.DataType.HTML;
            } else if (StringUtils.isNotBlank(dataEntry.get(LINK)) || StringUtils.isNotBlank(dataEntry.get(H5LINK))) {
                return CMSItemInfo.DataType.LINK;
            }
        }
        return CMSItemInfo.DataType.ANONYMOUS;
    }

    /**
     * 元素交互行为
     *
     * @param dataEntry
     * @return
     */
    private List<CMSItemInfo.ActionType> parseActionType(Map<String, String> dataEntry) {
        List<CMSItemInfo.ActionType> actionTypes = new ArrayList<CMSItemInfo.ActionType>();
        if (dataEntry != null) {
            if (StringUtils.isNotBlank(dataEntry.get(LINK)) || StringUtils.isNotBlank(dataEntry.get(H5LINK))) {
                actionTypes.add(CMSItemInfo.ActionType.LINK);
            }
            if (StringUtils.isNotBlank(dataEntry.get(CARD_ID))) {
                actionTypes.add(CMSItemInfo.ActionType.CARD);
            }
            if (StringUtils.isNotBlank(dataEntry.get(BAG_ID))) {
                actionTypes.add(CMSItemInfo.ActionType.BAG);
            }
            //不加购物车
            if (StringUtils.isNotBlank(dataEntry.get(ITEM_ID)) && !"0".equalsIgnoreCase(dataEntry.get(ITEM_ID))) {
                actionTypes.add(CMSItemInfo.ActionType.CART);
            }
        }
        return actionTypes;
    }

    protected Map<String, String> setDataTypeAndActionType(Map<String, String> dataEntry) {
        if (dataEntry != null) {
            dataEntry.put(DATA_TYPE, String.valueOf(parseDataType(dataEntry)));
            dataEntry.put(ACTION_TYPE, JSON.toJSONString(parseActionType(dataEntry).toArray()));
            {
                //后台保存数据将一些系统属性保存了，此处过滤避免数据泄露
                dataEntry.remove(PRICE);
                dataEntry.remove(STOCK);
                dataEntry.remove(SOLDOUT_STATUS);
            }
        }
        return dataEntry;
    }

    protected List<Object> appendSpm(CommonParametersWrapper wrapper, List<CmsDataDO> cmsDataDOs, int startId) {
        List<Object> dataList = null;
        if (cmsDataDOs != null && cmsDataDOs.size() > 0) {
            dataList = new ArrayList<Object>();
            int id = startId >= 0 ? startId : 0;
            for (CmsDataDO data : cmsDataDOs) {
                if (StringUtils.isNotBlank(data.getPropertyValue())) {
                    Map<String, String> dataEntry = JSON.parseObject(data.getPropertyValue(), new TypeReference<Map<String, String>>() {
                    });
                    if (dataEntry != null) {
                        //设置SPM
                        dataEntry = setSpm(wrapper, dataEntry, id);
                        //设置数据TYPE
                        dataEntry = setDataTypeAndActionType(dataEntry);
                        id++;
                        dataList.add(dataEntry);
                    }
                }
            }
        }
        return dataList;
    }


    @Override
    public String toString() {
        return "DataProcessor{" +
                "description='" + description + '\'' +
                '}';
    }
}
